package com.dw.love.dwade.utils;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.util.Log;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
public class BitmapUtil {

	private static String TAG = "BitmapUtil";

	public static Bitmap comp(Bitmap image) {

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
		if (baos.toByteArray().length / 1024 > 1024) {//
			// 判断如果图片大于1M,进行压缩避免在生成图片（BitmapFactory.decodeStream）时溢出
			baos.reset();// 重置baos即清空baos
			image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//
			// 这里压缩50%，把压缩后的数据存放到baos中
		}
		ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		// 开始读入图片，此时把options.inJustDecodeBounds 设回true了
		newOpts.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
		newOpts.inJustDecodeBounds = false;
		int w = newOpts.outWidth;
		int h = newOpts.outHeight;
		// 现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
		float hh = 1280f;// 这里设置高度为
		float ww = 720f;// 这里设置宽度为
		// 缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
		int be = 1;// be=1表示不缩放
		if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
			be = (int) (newOpts.outWidth / ww);
		} else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
			be = (int) (newOpts.outHeight / hh);
		}
		if (be <= 0)
			be = 1;
		newOpts.inSampleSize = be;// 设置缩放比例
		// 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
		isBm = new ByteArrayInputStream(baos.toByteArray());
		bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
		return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩
	}

	public static Bitmap compressImage(Bitmap image) {

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//
		// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
		int options = 100;
		Log.d(TAG, "compressImage: 压缩前baos:"+baos.toByteArray().length);
		Log.d(TAG, "compressImage: 压缩前image(bitmap):"+image.getByteCount());
		while (baos.toByteArray().length / 1024 > 100) { //
			// 循环判断如果压缩后图片是否大于100kb,大于继续压缩
			baos.reset();// 重置baos即清空baos
			image.compress(Bitmap.CompressFormat.JPEG, options, baos);//
			// 这里压缩options%，把压缩后的数据存放到baos中
			options -= 10;// 每次都减少10
		}
		ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//
		// 把压缩后的数据baos存放到ByteArrayInputStream中
		Bitmap bitmap = BitmapFactory.decodeStream(isBm);//
		Log.d(TAG, "compressImage: 压缩后isBm:"+isBm.available());
		Log.d(TAG, "compressImage: 压缩后image(bitmap):"+bitmap.getByteCount());
		// 把ByteArrayInputStream数据生成图片

		return bitmap;
	}

	public static Bitmap GetLocalBitmap(String url) {
		Bitmap bitmap = null;
		try {
			File file = new File(url);
			if (file.exists()) {
				bitmap = BitmapFactory.decodeFile(url);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return bitmap;
	}

	public static Bitmap imageZoom(Bitmap image) {
		// 图片允许最大空间 单位：KB
		double maxSize = 500;
		// 将bitmap放至数组中，意在bitmap的大小（与实际读取的原文件要大）
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
		byte[] b = baos.toByteArray();
		// 将字节换成KB
		double mid = b.length / 1024;
		// 判断bitmap占用空间是否大于允许最大空间 如果大于则压缩 小于则不压缩
		if (mid > maxSize) {
			// 获取bitmap大小 是允许最大大小的多少倍
			double i = mid / maxSize;
			// 开始压缩 此处用到平方根 将宽带和高度压缩掉对应的平方根倍
			// （1.保持刻度和高度和原bitmap比率一致，压缩后也达到了最大大小占用空间的大小）
			image = zoomImage(image, image.getWidth() / Math.sqrt(i),
					image.getHeight() / Math.sqrt(i));
		}
		return image;
	}

	/***
	 * 图片的缩放方法
	 * 
	 * @param bgimage
	 *            ：源图片资源
	 * @param newWidth
	 *            ：缩放后宽度
	 * @param newHeight
	 *            ：缩放后高度
	 * @return
	 */
	public static Bitmap zoomImage(Bitmap bgimage, double newWidth,
                                   double newHeight) {
		// 获取这个图片的宽和高
		float width = bgimage.getWidth();
		float height = bgimage.getHeight();
		// 创建操作图片用的matrix对象
		Matrix matrix = new Matrix();
		// 计算宽高缩放率
		float scaleWidth = ((float) newWidth) / width;
		float scaleHeight = ((float) newHeight) / height;
		// 缩放图片动作
		matrix.postScale(scaleWidth, scaleHeight);
		Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width,
				(int) height, matrix, true);
		return bitmap;
	}

	/**
	 * 获取照相机路径进行缩放
	 * 
	 * @param filePath
	 * @return
	 */
	public static Bitmap createImageThumbnail(String filePath) {
		Bitmap bitmap = null;
		BitmapFactory.Options opts = new BitmapFactory.Options();
		// 先指定原始大小
		opts.inSampleSize = 1;
		opts.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(filePath, opts);

		opts.inSampleSize = computeSampleSize(opts, 500);
		opts.inJustDecodeBounds = false;
		opts.inDither = false;
		opts.inPreferredConfig = Bitmap.Config.RGB_565;

		try {
			bitmap = BitmapFactory.decodeFile(filePath, opts);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return bitmap;
	}

	/**
	 * 获取本地图库路径流加selectedImageUri路径进行缩放
	 *
	 * @param filePath
	 * @return
	 */
	public static Bitmap getBitpMap(InputStream is, Uri selectedImageUri,
                                    Activity activity) {
		ParcelFileDescriptor pfd = null;
		try {
			pfd = activity.getContentResolver().openFileDescriptor(
					selectedImageUri, "r");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		java.io.FileDescriptor fd = pfd.getFileDescriptor();
		BitmapFactory.Options options = new BitmapFactory.Options();
		// 先指定原始大小
		options.inSampleSize = 1;
		// 只进行大小判断
		options.inJustDecodeBounds = true;
		// 调用此方法得到options得到图片的大小
		BitmapFactory.decodeFileDescriptor(fd, null, options);
		// BitmapFactory.decodeStream(is, null, options);
		// 我们的目标是在800pixel的画面上显示。
		// 所以需要调用computeSampleSize得到图片缩放的比例
		options.inSampleSize = computeSampleSize(options, 500);
		// OK,我们得到了缩放的比例，现在开始正式读入BitMap数据
		options.inJustDecodeBounds = false;
		options.inDither = false;
		options.inPreferredConfig = Bitmap.Config.ARGB_8888;

		// 根据options参数，减少所需要的内存
		// Bitmap sourceBitmap = BitmapFactory.decodeFileDescriptor(fd, null,
		// options);
		Bitmap sourceBitmap = BitmapFactory.decodeStream(is, null, options);
		return sourceBitmap;
	}

	// 这个函数会对图片的大小进行判断，并得到合适的缩放比例，比如2即1/2,3即1/3
	public static int computeSampleSize(BitmapFactory.Options options,
			int target) {
		int w = options.outWidth;
		int h = options.outHeight;
		int candidateW = w / target;
		int candidateH = h / target;
		int candidate = Math.max(candidateW, candidateH);
		if (candidate == 0)
			return 1;
		if (candidate > 1) {
			if ((w > target) && (w / candidate) < target)
				candidate -= 1;
		}
		if (candidate > 1) {
			if ((h > target) && (h / candidate) < target)
				candidate -= 1;
		}
		return candidate;
	}

	public static Bitmap getimage(String srcPath) {
		Bitmap bitmap = null;
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		newOpts.inDither = false;
		newOpts.inPurgeable = true;
		newOpts.inInputShareable = true;
		newOpts.inPreferredConfig = Bitmap.Config.RGB_565;
		// 开始读入图片，此时把options.inJustDecodeBounds 设回true了
		newOpts.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空

		newOpts.inSampleSize = computeSampleSize1(newOpts, -1, 450 * 450);

		newOpts.inJustDecodeBounds = false;
		// 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
		try {
			bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
		} catch (Exception e) {
			e.printStackTrace();
		}
		// return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
		return bitmap;
	}

	public static final float DISPLAY_WIDTH = 300;
	public static final float DISPLAY_HEIGHT = 300;

	/**
	 * 从path中获取图片信息
	 *
	 * @param path
	 * @return
	 */
	public static Bitmap decodeBitmap(String path) {
		Bitmap bmp = decodeBitmap(path,DISPLAY_WIDTH,DISPLAY_HEIGHT);
		return bmp;
	}

	public static Bitmap decodeBitmap(String path, float width, float height){
		BitmapFactory.Options op = new BitmapFactory.Options();
		op.inDither = false;
		op.inPurgeable = true;
		op.inInputShareable = true;
		op.inPreferredConfig = Bitmap.Config.RGB_565;
		// inJustDecodeBounds
		// If set to true, the decoder will return null (no bitmap), but the
		// out…
		op.inJustDecodeBounds = true;
		Bitmap bmp = BitmapFactory.decodeFile(path, op); // 获取尺寸信息
		// 获取比例大小
		int wRatio = (int) Math.ceil(op.outWidth / width );
		int hRatio = (int) Math.ceil(op.outHeight / height );
		// 如果超出指定大小，则缩小相应的比例
		if (wRatio > 1 && hRatio > 1) {
			if (wRatio > hRatio) {
				op.inSampleSize = wRatio;
			} else {
				op.inSampleSize = hRatio;
			}
		}
		op.inJustDecodeBounds = false;
		try {
			bmp = BitmapFactory.decodeFile(path, op);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return bmp;
	}
	
	public static int computeSampleSize1(BitmapFactory.Options options,
			int minSideLength, int maxNumOfPixels) {
		int initialSize = computeInitialSampleSize1(options, minSideLength,
				maxNumOfPixels);

		int roundedSize;
		if (initialSize <= 8) {
			roundedSize = 1;
			while (roundedSize < initialSize) {
				roundedSize <<= 1;
			}
		} else {
			roundedSize = (initialSize + 7) / 8 * 8;
		}

		return roundedSize;
	}

	private static int computeInitialSampleSize1(BitmapFactory.Options options,
			int minSideLength, int maxNumOfPixels) {
		double w = options.outWidth;
		double h = options.outHeight;

		int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math
				.sqrt(w * h / maxNumOfPixels));
		int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(
				Math.floor(w / minSideLength), Math.floor(h / minSideLength));

		if (upperBound < lowerBound) {
			// return the larger one when there is no overlapping zone.
			return lowerBound;
		}

		if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
			return 1;
		} else if (minSideLength == -1) {
			return lowerBound;
		} else {
			return upperBound;
		}
	}

	/**
	 * 获取压缩的图片
	 * 
	 * @param srcPath
	 * @return
	 */
/*	public static File getZoomPicFile(String srcPath) {
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		newOpts.inJustDecodeBounds = true;// 只读边,不读内容
		Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);

		newOpts.inJustDecodeBounds = false;
		int w = newOpts.outWidth;
		int h = newOpts.outHeight;
		float hh = 1080f;//
		float ww = 720f;//
		int be = 1;
		if (w > h && w > ww) {
			be = (int) (newOpts.outWidth / ww);
		} else if (w < h && h > hh) {
			be = (int) (newOpts.outHeight / hh);
		}
		if (be <= 0)
			be = 1;
		newOpts.inSampleSize = be;// 设置采样率

		newOpts.inPreferredConfig = Config.RGB_565;// 该模式是默认的,可不设
		newOpts.inPurgeable = true;// 同时设置才会有效
		newOpts.inInputShareable = true;// 。当系统内存不够时候图片自动被回收

		bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
		// return compressBmpFromBmp(bitmap);//原来的方法调用了这个方法企图进行二次压缩
		// 其实是无效的,大家尽管尝试
		
		return saveFile(bitmap);
	}*/

	/**
	 * 压缩图片
	 * @param srcPath
	 * @return
	 */
/*	public static File getZoomPicFile500(String srcPath){
		return saveFile(createImageThumbnail(srcPath));
	}*/
	
	/**
	 * 压缩后的文件
	 * @param bm
	 * @return
	 */
/*	public static File saveFile(Bitmap bm) {
		String filePath = Constant.picTempDic+ "/"+TimeUtils.getTimestamp() + ".jpg";
		return saveFile(bm, filePath, 70);
	}*/

	/**
	 * 保存文件
	 * @param bm
	 * @param savaPath
	 * @return
	 */
/*	public static File savaFile(Bitmap bm, String savaPath){
		return saveFile(bm, savaPath, 100);
	}
	*/
	/**
	 * 保存文件
	 * @param bm Bitmap
	 * @param savaPath  保存路径
	 * @param quality  保存的质量
	 * @return
	 */
/*	public static File saveFile(Bitmap bm, String savaPath, int quality) {
		File dirFile = null;
		 File myCaptureFile = null;
//		String path = Environment.getExternalStorageDirectory().getAbsolutePath()+ "/towermanagement/temp";
//		String filePath = Constant.picTempDic+ "/"+TimeUtils.getTimestamp() + ".jpg";
		 Bitmap.CompressFormat commf = Bitmap.CompressFormat.JPEG;
		 String exfileName = CommonUtils.getExtensionName(savaPath).toLowerCase();
		 if("png".equals(exfileName)){
			 commf = Bitmap.CompressFormat.PNG;
		 }
		try {
			dirFile = new File(CommonUtils.getFileDicName(savaPath));
			if (!dirFile.exists()) {
				dirFile.mkdirs();
			}
			myCaptureFile = new File(savaPath);
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(savaPath));
			bm.compress(commf, quality, bos);
			bos.flush();
			bos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return myCaptureFile;
	}*/
	
	/**
	 * 清除缓存文件夹
	 */
/*	public static void deleteTempDic() {
		
		File file = new File( Constant.picTempDic);
        if(!file.exists()){
        	return;
        }
		if (file.isDirectory()) {
			File[] childFiles = file.listFiles();
			if (childFiles == null || childFiles.length == 0) {
				file.delete();
				return;
			}

			for (int i = 0; i < childFiles.length; i++) {
			    childFiles[i].delete();
			}
			file.delete();
		}
	}*/
}
